import type { Form, FormExpose } from '@/components/Form';
import { nextTick, ref, unref } from 'vue';
import { isEmptyObject, isObject, isFalsy, isTruthy } from '@sindresorhus/is';

export const useForm = () => {
  const formRef = ref<typeof Form & FormExpose>();
  const elFormRef = ref<ComponentRef<typeof Form>>();

  const register = (ref: typeof Form & FormExpose, elRef: ComponentRef<typeof Form>) => {
    // 代码库里的form实例, 包含各种expose 方法等
    formRef.value = ref;
    // element-plus 的form实例, 包含各种方法等
    elFormRef.value = elRef;
  };

  const getForm = async () => {
    // 等渲染完成
    await nextTick();
    const form = unref(formRef);
    if (!form) {
      throw new Error('formRef is not registered');
    }
    return form;
  };

  const methods = {
    getFormData: async <T = Recordable>(filterEmptyVal = true): Promise<T> => {
      const form = await getForm();
      const model = form?.formModel as any;

      if (filterEmptyVal) {
        type StringKeyObject = Record<string, any>;
        return Object.keys(model).reduce((prev: StringKeyObject, curr) => {
          const currValue = model[curr];
          // {a:{}, b:1, c:'', d:0, e:null} => {b:1}
          if (isTruthy(currValue) && !(isObject(currValue) && isEmptyObject(currValue))) {
            prev[curr] = currValue;
          }

          return prev;
        }, {}) as T;
      }

      return model as T;
    }
  };

  return {
    formRegister: register,
    formMethods: methods
  };
};
